#include "choosdictionary.h"
#include "ui_choosdictionary.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QTextStream>
#include <QProgressBar>
#include <QDebug>

ChoosDictionary::ChoosDictionary(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ChoosDictionary)
{
    ui->setupUi(this);
    tmodel = new QSqlTableModel(this);
    tmodel->setTable("dictionary");
    tmodel->setSort(1, Qt::AscendingOrder);
    tmodel->setEditStrategy(QSqlTableModel::OnFieldChange);
    tmodel->select();
    tmodel->setHeaderData(1, Qt::Horizontal, tr("English words"));
    tmodel->setHeaderData(2, Qt::Horizontal, tr("Hungarian words"));
    ui->tableView_Dictionary->setModel(tmodel);
    ui->tableView_Dictionary->setColumnHidden(0, true);
    ui->tableView_Dictionary->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    QRegExp rx("^(?!\\s)((?!\\*)(?!\\s\\s).)*$");
    newWordEngValidator = new QRegExpValidator(rx, this);
    newWordHunValidator = new QRegExpValidator(rx, this);
    ui->lineEdit_NewEnglish->setValidator(newWordEngValidator);
    ui->lineEdit_NewHungarian->setValidator(newWordHunValidator);
    fetchAllDataFromDB();
    wModifyMode = false;
}

ChoosDictionary::~ChoosDictionary()
{
    delete tmodel;
    delete newWordEngValidator;
    delete newWordHunValidator;
    delete ui;
}

void ChoosDictionary::fetchAllDataFromDB()
{
    while (tmodel->canFetchMore())
        tmodel->fetchMore();
}

void ChoosDictionary::searchThisRow(int theme)
{
    for (int row = 0; row < tmodel->rowCount(); ++row) {
        QSqlRecord record = tmodel->record(row);
        if (record.value("id").toInt() == theme) {
            ui->tableView_Dictionary->selectRow(row);
            break;
        }
    }
}

void ChoosDictionary::on_actionNewWordsChanged_triggered()
{
    int newEnLen = ui->lineEdit_NewEnglish->text().length();
    int newHuLen = ui->lineEdit_NewHungarian->text().length();
    if (newEnLen > 0 && newHuLen > 0) {
        ui->pushButton_NewWordsCancel->setEnabled(true);
        ui->pushButton_NewWordsSubmit->setEnabled(true);
    }
    else {
        if (!wModifyMode)
            ui->pushButton_NewWordsCancel->setEnabled(false);
        ui->pushButton_NewWordsSubmit->setEnabled(false);
    }
}

void ChoosDictionary::on_pushButton_NewWordsSubmit_clicked()
{
    this->setCursor(Qt::WaitCursor);
    QString newEngString = ui->lineEdit_NewEnglish->text().trimmed();
    QString newHunString = ui->lineEdit_NewHungarian->text().trimmed();
    QSqlQuery query;
    int id = 0;
    if (wModifyMode) {
        id = wModifyID;
        query.prepare("UPDATE dictionary set eng=:eng, hun=:hun where id=:id");
        query.bindValue(":id", id);
    }
    else
        query.prepare("INSERT INTO dictionary (eng, hun) "
                      "VALUES (:eng, :hun)");
    query.bindValue(":eng", newEngString);
    query.bindValue(":hun", newHunString);
    query.exec();
    if (wModifyMode) {
        wModifyMode = false;
        ui->label_ModifiedNr->setText("");
        ui->tableView_Dictionary->setFocus();
    }
    else {
        id = query.lastInsertId().toInt();
        ui->lineEdit_NewEnglish->setFocus();
    }
    ui->lineEdit_NewEnglish->clear();
    ui->lineEdit_NewHungarian->clear();
    tmodel->select();
    fetchAllDataFromDB();
    searchThisRow(id);
    this->setCursor(Qt::ArrowCursor);
}

void ChoosDictionary::on_pushButton_DeleteWords_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView_Dictionary->selectionModel();
    QModelIndexList indexes = selectionModel->selectedRows();
    int selnr = indexes.count();
    if (!selnr) {
        QMessageBox::information(this, tr("No row selected"), tr("Not selected a row either."));
        return;
    }
    bool yesToAll = false;
    QMessageBox::StandardButtons questionButtons;
    if (selnr > 1)
        questionButtons = QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll;
    else
        questionButtons = QMessageBox::Yes | QMessageBox::No;
    QSqlDatabase::database().transaction();
    for (int i = 0; i < selnr; ++i) {
        int row = indexes.at(i).row();
        int id = tmodel->record(row).value(0).toInt();
        QString currentWordEn = tmodel->record(row).value(1).toString();
        QString currentWordHu = tmodel->record(row).value(2).toString();
        int answer = 0;
        if (!yesToAll) {
            QString message(tr("Delete the word"));
            message.append(": <br><b>" + currentWordEn + " - " + currentWordHu);
            answer = QMessageBox::question(this, tr("Are you sure?"), message, questionButtons, QMessageBox::No);
        }
        if (answer == QMessageBox::YesToAll)
            yesToAll = true;
        if (answer == QMessageBox::NoToAll)
            break;
        if (yesToAll || answer == QMessageBox::Yes) {
            QSqlQuery delquery;
            delquery.prepare("DELETE FROM dictionary WHERE id=:id");
            delquery.bindValue(":id", id);
            delquery.exec();
        }
    }
    QSqlDatabase::database().commit();
    tmodel->select();
    fetchAllDataFromDB();
}

void ChoosDictionary::on_pushButton_ImportFromfile_clicked()
{
    QString filename;
    filename = QFileDialog::getOpenFileName(this, tr("Choose input file for import dictionary wordpairs"), QDir::currentPath(), tr("Text files (*.txt)"));
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::information(this, tr("Open error"), tr("Cannot open selected file."));
        return;
    }
    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString line = in.readLine();
    if (line.compare(":AngolMix:Dictionary:", Qt::CaseInsensitive)) {
        QMessageBox::information(this, tr("File format error", "noheadline"), tr("The file is not compatible with AMix Dictionary"));
        file.close();
        return;
    }
    int wordPairsCnt = 0;
    int processedlineCnt = 1;
    int errorlinesCnt = 0;
    QProgressBar importProgress;
    importProgress.setFixedSize(240, 60);
    importProgress.setMaximum((int) file.size());
    importProgress.setWindowModality(Qt::ApplicationModal);
    importProgress.setWindowFlags(Qt::SplashScreen);
    importProgress.show();
    QSqlDatabase::database().transaction();
    while (!in.atEnd()) {
        line = in.readLine();
        ++processedlineCnt;
        importProgress.setValue((int) file.pos());
        QApplication::processEvents();
        if (line.compare("") == 0)
            continue;
        else {
            //normal wordpair row
            QStringList splited = line.split(QString("->"));
            if (splited.count() != 2) {
                ++errorlinesCnt;
                int answer = QMessageBox::question(this, tr("File format error"), tr("Error in tasks processing at line %n.\nContinue processing?", "", processedlineCnt), QMessageBox::Yes, QMessageBox::No);
                if (answer == QMessageBox::Yes)
                    continue;
                else
                    break;
            }
            QSqlQuery addWordPairQuery;
            QString r_wordEn(splited.at(0));
            QString r_wordHu(splited.at(1));
            addWordPairQuery.prepare("INSERT INTO dictionary (eng, hun) VALUES (:eng, :hun)");
            addWordPairQuery.bindValue(":eng", r_wordEn.simplified());
            addWordPairQuery.bindValue(":hun", r_wordHu.simplified());
            addWordPairQuery.exec();
            ++wordPairsCnt;
        }
    }
    file.close();
    importProgress.hide();
    QString message;
    if (errorlinesCnt)
        message.append(tr("Import ready, but found errors in %n lines!\n", "", errorlinesCnt));
    else
        message.append(tr("Import ready for approve.\n"));
    message.append(tr("Word pairs: %n", "added wordpairs", wordPairsCnt));
    int answer;
    answer = QMessageBox::question(this, tr("Are you sure?"), message, QMessageBox::Yes | QMessageBox::No);
    if (answer == QMessageBox::Yes)
        QSqlDatabase::database().commit();
    else
        QSqlDatabase::database().rollback();
    tmodel->select();
    fetchAllDataFromDB();
}

void ChoosDictionary::on_pushButton_ExportTofile_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView_Dictionary->selectionModel();
    QModelIndexList indexes = selectionModel->selectedRows();
    int selnr = indexes.count();
    if (!selnr) {
        QMessageBox::information(this, tr("No items selected"), tr("Please highlight the rows to be exported!"));
        return;
    }
    QQueue<int> tIDlist;
    for (int i = 0; i < selnr; ++i) {
        int row = indexes.at(i).row();
        int id = tmodel->record(row).value(0).toInt();
        tIDlist.enqueue(id);
    }
    exportReallyProcessing(tIDlist);
}

void ChoosDictionary::on_pushButton_ExportAllTofile_clicked()
{
    QSqlQuery query("SELECT id FROM dictionary");
    QQueue<int> tIDlist;
    while (query.next())
        tIDlist.enqueue(query.record().value("id").toInt());
    exportReallyProcessing(tIDlist);
}

void ChoosDictionary::exportReallyProcessing(QQueue<int> &wIDs)
{
    QString filename;
    filename = QFileDialog::getSaveFileName(this, tr("Save to file"), QDir::currentPath(), tr("Text files (*.txt)"));
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::information(this, tr("Save error"), "Cannot save to selected file.");
        return;
    }
    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << ":AngolMix:Dictionary:\n";
    int wordPairsCnt = wIDs.count();
    while (wIDs.count()) {
        int id = wIDs.dequeue();
        QSqlQuery query;
        query.prepare("SELECT eng, hun FROM dictionary WHERE id=:id");
        query.bindValue(":id", id);
        query.exec();
        query.next();
        QString wordEngString = query.record().value("eng").toString();
        QString wordHunString = query.record().value("hun").toString();
        out << wordEngString << "*" << wordHunString << "\n";
    }
    file.close();
    QString message(tr("Export completed successfully.\n"));
    message.append(tr("Wordpairs: %n", "", wordPairsCnt));
    QMessageBox::information(this, tr("Export completed."), message);
}

void ChoosDictionary::on_pushButton_NewWordsCancel_clicked()
{
    wModifyMode = false;
    ui->label_ModifiedNr->setText("");
    ui->lineEdit_NewEnglish->clear();
    ui->lineEdit_NewHungarian->clear();
    ui->lineEdit_NewEnglish->setFocus();
}

void ChoosDictionary::on_tableView_Dictionary_doubleClicked(const QModelIndex &index)
{
    int rowindex = index.row();
    int colindex = index.column();
    wModifyMode = true;
    wModifyID = tmodel->record(rowindex).value(0).toInt();
    ui->label_ModifiedNr->setText("#" + QString::number(rowindex + 1));
    ui->lineEdit_NewEnglish->setText(tmodel->record(rowindex).value(1).toString());
    ui->lineEdit_NewHungarian->setText(tmodel->record(rowindex).value(2).toString());
    if (colindex == 1)
        ui->lineEdit_NewEnglish->setFocus();
    else //colindex==2
        ui->lineEdit_NewHungarian->setFocus();
}
